package com.ssy.lingxi.enhance.serviceimpl.process;

import com.querydsl.core.BooleanBuilder;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.enhance.constant.*;
import com.ssy.lingxi.enhance.entity.*;
import com.ssy.lingxi.enhance.handler.async.OrderAsyncService;
import com.ssy.lingxi.enhance.handler.jpa.QueryDslUtil;
import com.ssy.lingxi.enhance.model.dto.DiscontinueDTO;
import com.ssy.lingxi.enhance.model.qo.ProduceNoticeOrderQO;
import com.ssy.lingxi.enhance.model.vo.OuterAndInnerVO;
import com.ssy.lingxi.enhance.model.vo.ProduceNoticeOrderListVO;
import com.ssy.lingxi.enhance.repository.InnerWorkflowRecordRepository;
import com.ssy.lingxi.enhance.repository.OuterWorkflowRecordRepository;
import com.ssy.lingxi.enhance.repository.ProduceNoticeOrderDetailRepository;
import com.ssy.lingxi.enhance.repository.ProduceNoticeOrderRepository;
import com.ssy.lingxi.enhance.service.process.ProcessAllService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 加工能力 - 确认生产通知单(加工企业) - 生产通知单查询 - 业务实现层
 * @author fhj
 * @date 2020/10/20
 * @version 2.0.0
 */
@Slf4j
@Service
public class ProcessAllServiceImpl implements ProcessAllService {

    @Resource
    private QueryDslUtil queryDslUtil;
    @Resource
    private ProduceNoticeOrderRepository produceNoticeOrderRepository;
    @Resource
    private ProduceNoticeOrderDetailRepository produceNoticeOrderDetailRepository;
    @Resource
    private InnerWorkflowRecordRepository innerWorkflowRecordRepository;
    @Resource
    private OuterWorkflowRecordRepository outerWorkflowRecordRepository;
    @Resource
    private OrderAsyncService orderAsyncService;

    /**
     * 外部状态/内部状态
     * */
    @Override
    public Wrapper<OuterAndInnerVO> outerAndInner() {
        OuterAndInnerVO vo = new OuterAndInnerVO();
        vo.setOuterList(PNOOuterStatusEnum.getAll());
        vo.setInnerList(PNOProcessInnerStatusEnum.getAll());
        return Wrapper.success(vo);
    }

    /**
     * 列表
     * */
    @Override
    public Wrapper<PageData<ProduceNoticeOrderListVO>> list(ProduceNoticeOrderQO qo, UserLoginCacheDTO user) {
        //查询表实体 - 生产通知单
        QProduceNoticeOrderDO pno = QProduceNoticeOrderDO.produceNoticeOrderDO;

        //查询条件构造 - 必要条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(pno.processMemberId.eq(user.getMemberId()));
        predicates.and(pno.processRoleId.eq(user.getMemberRoleId()));
        predicates.and(pno.processInnerStatus.isNotNull());

        return Wrapper.success(queryDslUtil.getProcessPNOList(qo, pno, predicates));
    }

    /**
     * 中止
     * */
    @Override
    @Transactional
    public Wrapper<Void> discontinue(DiscontinueDTO dto, UserLoginCacheDTO user) {
        //根据ID获取生产通知单详情
        ProduceNoticeOrderDO produceNoticeOrder = produceNoticeOrderRepository.findById(dto.getId()).orElse(null);
        if(produceNoticeOrder == null) {
            return Wrapper.fail(ResponseCode.ENHANCE_BY_ID_NOT_FOUND_PNO);
        }
        if(!(produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_ADD_DELIVERY.getCode())
                || produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_ADD_LOGISTICS.getCode())
                || produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_DELIVERY.getCode())
                || produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_ADD_STORAGE.getCode())
                || produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_RECEIVE.getCode())
                || produceNoticeOrder.getOuterStatus().equals(PNOOuterStatusEnum.TO_BE_CONFIRM_RECEIPT.getCode()))) {
            return Wrapper.fail("生产通知单现在的状态不允许被中止");
        }

        //记录加工企业内部工作流记录
        InnerWorkflowRecordDO innerWorkflowRecord = new InnerWorkflowRecordDO();
        innerWorkflowRecord.setProduceNoticeOrderId(produceNoticeOrder.getId());
        innerWorkflowRecord.setUserId(user.getUserId());
        innerWorkflowRecord.setMemberId(user.getMemberId());
        innerWorkflowRecord.setRoleId(user.getMemberRoleId());
        innerWorkflowRecord.setType(RoleTypeEnum.PROCESS.getCode());
        innerWorkflowRecord.setStep(produceNoticeOrder.getProcessInnerStatus());
        innerWorkflowRecord.setOperator(user.getUserName());
        innerWorkflowRecord.setDepartment(user.getUserOrgName());
        innerWorkflowRecord.setJobTitle(user.getUserJobTitle());
        innerWorkflowRecord.setStatus("已中止");
        innerWorkflowRecord.setOperate("中止生产通知单");
        innerWorkflowRecord.setOperateTime(dto.getDiscontinueTime());
        innerWorkflowRecord.setOpinion(dto.getCause());
        innerWorkflowRecordRepository.saveAndFlush(innerWorkflowRecord);

        //记录外部工作流记录
        OuterWorkflowRecordDO outerWorkflowRecordDO = new OuterWorkflowRecordDO();
        outerWorkflowRecordDO.setProduceNoticeOrderId(produceNoticeOrder.getId());
        outerWorkflowRecordDO.setUserId(user.getUserId());
        outerWorkflowRecordDO.setMemberId(user.getMemberId());
        outerWorkflowRecordDO.setRoleId(user.getMemberRoleId());
        outerWorkflowRecordDO.setStep(produceNoticeOrder.getOuterStatus());
        outerWorkflowRecordDO.setRoleName(user.getMemberRoleName());
        outerWorkflowRecordDO.setStatus("已中止");
        outerWorkflowRecordDO.setOperate("中止生产通知单");
        outerWorkflowRecordDO.setOperateTime(System.currentTimeMillis());
        outerWorkflowRecordDO.setOpinion(dto.getCause());
        outerWorkflowRecordRepository.saveAndFlush(outerWorkflowRecordDO);

        //更新生产通知单各状态为已中止
        produceNoticeOrder.setDiscontinueTime(dto.getDiscontinueTime());
        produceNoticeOrder.setCause(dto.getCause());
        produceNoticeOrder.setOuterStatus(PNOOuterStatusEnum.DISCONTINUE.getCode());
        produceNoticeOrder.setStatus(PNOAllStatusEnum.DISCONTINUE.getCode());
        produceNoticeOrder.setSupplierInnerStatus(PNOSupplierInnerStatusEnum.ALREADY_DISCONTINUE.getCode());
        produceNoticeOrder.setProcessInnerStatus(PNOProcessInnerStatusEnum.ALREADY_DISCONTINUE.getCode());

        //如果通知单来源为加工订单且审核是不通过的话, 需要更新订单服务里的订单商品已加工数量（根据生产通知单明细将新增时加上去的已加工数量再减回去, 保持数量一致性）
        if(produceNoticeOrder.getSource().equals(SourceEnum.ORDER.getCode())) {
            List<ProduceNoticeOrderDetailDO> details = produceNoticeOrderDetailRepository.findByProduceNoticeOrderId(dto.getId());
            orderAsyncService.updateOrderProductProcessNum(details, Boolean.FALSE);
        }

        return Wrapper.success();
    }
}
